package com.lzx.adx.report.util;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lzx.adx.report.cache.CommonLocalCache;
import com.lzx.adx.report.dto.yunxuan.YunXuanRequest;
import com.lzx.adx.report.dto.yunxuan.YunXuanResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;


@Slf4j
public class YunXuanHelper {
    private static final String MAC_NAME = "HmacSHA1";
    private static final String ENCODING = "UTF-8";

    public final static String url = "https://api.cps.yunxuan.qq.com/gateway/searchOrders";
    public final static String apiAppKey = "APID6dad0a65c35244b281e133b028d65e52";
    public final static String apiAppSecret = "Hwb1osLP9XaD4dA7EbLyID9YPWOFx86n";
    public final static Long companyId = 185891370406L;

    private static String getGMTTime(){
        Calendar cd = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        String GMTTime = sdf.format(cd.getTime());
        return GMTTime;
    }

        public static Long getCurrentMax(){
        LocalDate today = LocalDate.now(); // 获取当前日期
        LocalDateTime endOfDay = LocalDateTime.of(today, LocalTime.MAX); // 当天的最大LocalDateTime

        return endOfDay.toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    private static String sortQueryParams(String queryParam){
        // parameters should be in alphabetical order
        if (queryParam == null || queryParam == ""){
            return "";
        }

        String[] queryParams = queryParam.split("&");
        Map<String, String> queryPairs = new TreeMap<>();
        for(String query: queryParams){
            String[] kv = query.split("=");
            queryPairs.put(kv[0], kv[1]);
        }

        StringBuilder sortedParamsBuilder = new StringBuilder();
        Iterator iter = queryPairs.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry entry = (Map.Entry) iter.next();
            sortedParamsBuilder.append(entry.getKey());
            sortedParamsBuilder.append("=");
            sortedParamsBuilder.append(entry.getValue());
            sortedParamsBuilder.append("&");
        }
        String sortedParams = sortedParamsBuilder.toString();
        sortedParams = sortedParams.substring(0, sortedParams.length() - 1);
        return sortedParams;
    }

    private static byte[] HmacSHA1Encrypt(String encryptText, String encryptKey) throws Exception {
        byte[] data = encryptKey.getBytes(ENCODING);
        SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
        Mac mac = Mac.getInstance(MAC_NAME);
        mac.init(secretKey);
        byte[] text = encryptText.getBytes(ENCODING);
        return mac.doFinal(text);
    }

    private static String base64Encode(byte[] key) {
        final Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(key);
    }

    private static String getMD5(String str) {
        String md5Hex = DigestUtils.md5Hex(str);
        return md5Hex;
    }

    public static void main(String[] args) throws Exception {


        YunXuanResponse execute = getDataListPage(1);


        log.info(JSON.toJSONString(execute));

    }


    public static YunXuanResponse getDataListPage(Integer pageNumber) throws Exception{



        YunXuanRequest yunXuanRequest = new YunXuanRequest();
        yunXuanRequest.setPageNum(pageNumber);
        yunXuanRequest.setPageSize(50);

        YunXuanRequest.YunXuanDetail yunXuanDetail = new YunXuanRequest.YunXuanDetail();
        yunXuanDetail.setType(2);
        yunXuanDetail.setSharer_id(companyId);
//        yunXuanDetail.setStart_time(1730874108000L);
        yunXuanDetail.setStart_time(getBeginTime());
        yunXuanDetail.setEnd_time(getCurrentMax());
//        yunXuanDetail.setOrder_no("24111597653152");
        yunXuanRequest.setQueryCriteria(yunXuanDetail);




        String host = "api.cps.yunxuan.qq.com";
        String httpMethod = "POST";
        String acceptHeader = "application/json";
        String contentType = "application/json";
        String reqBody = JSON.toJSONString(yunXuanRequest);
        String contentMD5 = base64Encode(getMD5(reqBody).getBytes());

        // Parse URL and assemble string to sign
        URL parsedUrl = new URL(url);
        String pathAndParams = parsedUrl.getPath();

        if (parsedUrl.getQuery() != null) {
            pathAndParams = pathAndParams + "?" + sortQueryParams(parsedUrl.getQuery());
        }

        System.out.println("pathAndParams:"+ pathAndParams);
        String xDate = getGMTTime();
        String stringToSign = String.format("x-date: %s\n%s\n%s\n%s\n%s\n%s", xDate, httpMethod, acceptHeader, contentType, contentMD5, pathAndParams);
        // Encode string with HMAC and base64
        byte[] hmacStr = HmacSHA1Encrypt(stringToSign, apiAppSecret);
        String signature = base64Encode(hmacStr);
        String authHeader = String.format("hmac id=\"%s\", algorithm=\"hmac-sha1\", headers=\"x-date\", signature=\"%s\"", apiAppKey, signature);

        System.out.println(stringToSign);


        Map<String,String> headers=new HashMap();
        headers.put("Accept", acceptHeader);
        headers.put("Host", host);
        headers.put("x-date", xDate);
        headers.put("Content-Type", contentType);
        headers.put("Content-MD5", contentMD5);
        headers.put("Authorization", authHeader);


        HttpRequest httpClient = HttpUtil.createPost(url).body(reqBody);
        httpClient.addHeaders(headers);

        String result = httpClient.execute().body();
        JSONObject jsonObject = JSONObject.parseObject(result);
        String statusCode = jsonObject.getString("code");
        boolean resultFlag = jsonObject.getBoolean("success");
        if(!resultFlag){
            return null;
        }
        String content = jsonObject.getString("data");

        return JSONObject.parseObject(content, YunXuanResponse.class);
    }



    public static Long getBeginTime(){
        CommonLocalCache instance = CommonLocalCache.getInstance();
        String yunXuanStime = instance.get("yunXuanStime");
        if(StringUtils.isBlank(yunXuanStime)){
            Long currentDayBegindayStime = getCurrentStartingTime();
            instance.put("yunXuanStime",String.valueOf(getCurrentStartingTime()));
            return currentDayBegindayStime;
        }else {
            //获取系统的时间和当前的时间比
            LocalDateTime cacheDate = Instant.ofEpochMilli(Long.valueOf(yunXuanStime)).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
            if(cacheDate.isBefore(getCurrentDate())){
                return getCurrentStartingTime();
            }else{
                return Long.valueOf(yunXuanStime);
            }
        }
    }


    public static Long getCurrentStartingTime() {
        LocalDate yesterday = LocalDate.now().minusDays(0);
        LocalTime midnight = LocalTime.MIDNIGHT;
        return LocalDateTime.of(yesterday, midnight).toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
    }

    public static Long getDelayCurrentTime() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime minusFiveMinutes = now.minusMinutes(5);
        return minusFiveMinutes.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
    }






    public static LocalDateTime getCurrentDate() {
        LocalDate yesterday = LocalDate.now().minusDays(0);
        LocalTime midnight = LocalTime.MIDNIGHT;
        return LocalDateTime.of(yesterday, midnight);
    }

}



